'''
Created on 28/05/2010

@author: eh01
'''
from datastore.resource import Resource
from datastore.uri import Uri
from runtime.service import Service
from spear import a2p_service
from string import Template
from xml.etree import ElementTree
import datetime
import logging
import re
import sys
import types

da_data_tns = 'http://xml.gov.au/edais/core/da.data.2.3.0r2'
naa_data_tns = 'http://xml.gov.au/edais/core/naa.data.2.3.0r2'
spec_data_tns = 'http://xml.gov.au/edais/core/specialisation.data.2.3.0r2'
ext_data_tns = 'http://www.edais.gov.au/nat/extension.data.2.3.0r2.v.0.5'
msg_data_tns = 'http://xml.gov.au/edais/core/msg.data.2.3.0r2'

SENDER_AUTHORITY = 'Authority'
SENDER_ID = 'ID'
SENDER_PROCESSROLE = 'ProcessRole'
SENDER_DOC_ID_INSTANCE_ID = 'InstanceID'

SOAP_ENV_NS = 'http://schemas.xmlsoap.org/soap/envelope/'

REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME = 'ReplyPublicStatusApplicationResponse'
REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NS = 'http://xml.gov.au/edais/bm/ReplyPublicStatusApplicationResponse.msg.2.3.0r2'

QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NAME = 'QueryRequestPublicStatusApplicationQuery'
QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NS = 'http://xml.gov.au/edais/bm/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2'

DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS = 'http://xml.gov.au/edais/bm/DeclareSaveStatusChangeApplicationNotification.msg.2.3.0r2'
DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NAME = 'DeclareSaveStatusChangeApplicationNotification'

RECEIPT_EXCEPTION_SIGNAL_MSG_NS = 'http://xml.gov.au/edais/bs/ReceiptExceptionSignal.msg.2.3.0r2'
RECEIPT_EXCEPTION_SIGNAL_MSG_NAME = 'ReceiptExceptionSignal'

RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NS = 'http://xml.gov.au/edais/bs/ReceiptAcknowledgementSignal.msg.2.3.0r2'
RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NAME = 'ReceiptAcknowledgementSignal'       
class SOAPService(Service):

    def cb_start(self, uri, action, res):      
        # process the post queues
        self.spaces.set_process(Uri('internal:edais/process/QueryPublicStatusApplication.2.3.0r2/'), self.cb_handle_query_public_status_application)
        self.spaces.set_process(Uri('internal:edais/process/DeclareStatusChangeApplication.2.3.0r2/'), self.cb_handle_declare_status_change_application)
        
    def cb_stop(self, uri, action, res):
        pass
    
    def cb_handle_query_public_status_application(self, uri, action, res):
        """
        Callback that handles the Query Public Status Application service.
        """
        self.logger.log(logging.DEBUG, uri)
        self.logger.log(logging.DEBUG, action)
        self.logger.log(logging.DEBUG, res)
        # ignore the exists action
        if action == 'exists':
            return
        # since we are putting the response as a child of the request we are going to receive a callback.
        if uri.split()[-1] == 'response':
            # we are not doing anything with the response so we can safely ignore it. 
            return
        mapping_index_rs = self.spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_message_request = str(res.form_data.decode())
        self.logger.log(logging.INFO, 'Received SOAP Message: %s' % soap_message_request)
        try:
            soap_message_response = self.handle_query_public_status_application(soap_message_request, self.spaces, mapping_index_rs, 'http://localhost:6101/edais/artefacts/biv/bm/queryPublicStatusApplication/QueryRequestPublicStatusApplicationQuery.msg.2.3.0r2.xsd', self.logger)
            return self.send_soap_response_rs(uri, self.spaces, soap_message_response)
        except Exception, e:
            env = ElementTree.Element('{%s}Envelope' % SOAP_ENV_NS)
            body = ElementTree.SubElement(env, '{%s}Body' % SOAP_ENV_NS)
            fault = ElementTree.SubElement(body, '{%s}Fault' % SOAP_ENV_NS)
            fault_code = ElementTree.SubElement(fault, 'faultcode')
            fault_code.text = 'Client'
            fault_string = ElementTree.SubElement(fault, 'faultstring')
            fault_string.text =  str(e)
            self.logger.log(logging.ERROR, e)
            self.logger.exception("Unable to handle web service call. (%s)", sys.exc_info()[1])            
            response_uri = uri + 'response'
            soap_message_response = self.get_elements_as_string(env) 
            return self.send_soap_response_rs(response_uri, self.spaces, soap_message_response)
                
    def cb_handle_declare_status_change_application(self, uri, action, res):
        """
        Callback that handles the Declare Status Change Application service.
        """
        self.logger.log(logging.INFO, uri)
        self.logger.log(logging.INFO, action)
        self.logger.log(logging.INFO, res)
        # ignore the exists action
        if action == 'exists':
            return
        if uri.split()[-1] == 'response':
            # we are not doing anything with the response so we can safely ignore it.
            return
        mapping_index_rs = self.spaces.get(Uri("internal:eplanning/mapping/index"))
        soap_message_request = str(res.form_data.decode())
        self.logger.log(logging.INFO, 'Received SOAP Message: %s' % soap_message_request)
        soap_message_response = self.handle_declare_status_change_application(soap_message_request, self.spaces, mapping_index_rs, self.logger)
        return self.send_soap_response_rs(uri, self.spaces, soap_message_response)

    def find_element(self, xpath, root_element):
        g = lambda parent_element, namespace, element_name: parent_element.find('./{%s}%s' % (namespace, element_name))
        parent_element = root_element
        curr_xpath = parent_element.tag
        finds = re.findall('{.*?}[^{]*', xpath)
        for find in finds:
            matches = re.match('{(.*?)}([^/]*)', find)
            namespace = matches.group(1)
            element_name = matches.group(2)
            parent_element = g(parent_element, namespace, element_name)
            if parent_element is None:
                raise Exception("Expected element '{%s}%s' in element '%s'" % (namespace, element_name, curr_xpath))
            curr_xpath += "/" + parent_element.tag
        return parent_element
    
    def send_soap_response_rs(self, uri, spaces, soap_message_response):
        """
        Adds the extension element to a extension elements dictionary.
        
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param element_name: Name of the element to be added to the dictionary.
        :param element: Element to be added to the dictionary.
        :rtype: None
        """          
        response_rs = Resource(type='term:base/services/http/response')
        self.logger.log(logging.INFO, "Responding with soap message: %s" % soap_message_response)
        response_rs.content = soap_message_response
        response_rs.content_type = 'text/xml'
        response_rs.content_length = len(response_rs.content)
        response_uri = uri + 'response'        
        spaces.put(response_uri, response_rs)
        return response_uri
    
    def get_sender_data(self, message_namespace, message_name, envelope_element):
        """
        Parses the request message and extracts the sender data. 
        
        :param message_namespace: The namespace which the message belongs to.
        :param message_name: The name of the message.
        :param envelope_element: The request soap message as an element.         
        :rtype: Sender data as a dictionary.
        """
        exception_reasons = []
        sender_data = {}
        datas = [(SENDER_DOC_ID_INSTANCE_ID, './{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}DocumentIdentification/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}InstanceID'),
                (SENDER_AUTHORITY, './{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}Authority'),
                (SENDER_ID, './{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ID'),
                (SENDER_PROCESSROLE, './{%s}Body/{%s}%s/{%s}StandardBusinessMessageHeader/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}SenderPartner/{http://xml.gov.au/edais/core/msg.data.2.3.0r2}ProcessRole')]
        for data in datas:
            try:
                sender_data[data[0]] = self.find_element(data[1] % (SOAP_ENV_NS, message_namespace, message_name, message_namespace), envelope_element).text
            except Exception, e:
                # if there is a problem finding the data lets save the exception message in a list and continue looking
                # for the other data we expect.
                exception_reasons.append(str(e))
        if exception_reasons:
            raise Exception("\n".join(exception_reasons))
        return sender_data
    
    def get_handle_declare_status_change_application_data(self, envelope_element, logger):
        """
        Gets the data required for the Declare Status Change Application service.
        
        :param envelope_element: SOAP Envelope element.
        :rtype: tuple (spear reference, sender data, council ref 1, council ref 2, list of exceptions)
        """        
        exceptions = []
        spear_ref, sender_data, council_ref_num_1, council_ref_num_2 = None, None, None, None
        try:
            spear_ref = self.find_element('./{%s}Body/{%s}%s/{%s}Application/{%s}ApplicationNumber'
                                          % (SOAP_ENV_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NAME, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, da_data_tns), envelope_element).text
            logger.log(logging.INFO, 'SPEAR Ref: %s' % spear_ref)
        except Exception, e:
            exceptions.append(e)
        try:
            sender_data = self.get_sender_data(DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NAME, envelope_element)
        except Exception, e:
            exceptions.append(e)
        try:
            council_ref_num_1 = self.find_element('./{%s}Body/{%s}%s/{%s}Specialisation/{%s}Extension/{%s}CouncilReferenceNumbers/{%s}ResponsibleAuthorityReferenceNumber1'
                                                  % (SOAP_ENV_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NAME, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, spec_data_tns, ext_data_tns, ext_data_tns), envelope_element).text
            logger.log(logging.INFO, 'Council Ref 1: %s' % council_ref_num_1)
        except Exception, e:
            exceptions.append(e)
        try:
            council_ref_num_2 = self.find_element('./{%s}Body/{%s}%s/{%s}Specialisation/{%s}Extension/{%s}CouncilReferenceNumbers/{%s}ResponsibleAuthorityReferenceNumber2'
                                                  % (SOAP_ENV_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NAME, DECLARE_SAVE_STATUS_CHANGE_APPLICATION_NOTIFICATION_MSG_NS, spec_data_tns, ext_data_tns, ext_data_tns), envelope_element).text            
            logger.log(logging.INFO, 'Council Ref 2: %s' % council_ref_num_2)
        except Exception, e:
            exceptions.append(e)

        return (spear_ref, sender_data, council_ref_num_1, council_ref_num_2, exceptions)
     
    def create_end_of_queue_application(self, msg_namespace, spear_ref):
        """
        Creates an end of queue application element. The end of queue application only has the ApplicationNumber
        element.
        
        :param msg_namespace: Namespace of the message that the application element belongs to.
        :param spear_ref: The spear reference number that has been enquired about.
        :rtype: application element.
        """                  
        application_element = ElementTree.Element('{%s}Application' % msg_namespace)
        application_number_element = ElementTree.SubElement(application_element, '{%s}ApplicationNumber' % da_data_tns)
        application_number_element.text = spear_ref
        return application_element
    
    def handle_declare_status_change_application(self, soap_message_request, spaces, mapping_index_rs, logger):
        """
        Handles the service call by parsing the request and generating the response. The service will extract the
        Council Reference Numbers and call another service to update the Council Reference Numbers in SPEAR. Currently 
        the implementation doesn't do this as the service to update the Council Reference Numbers in SPEAR has not 
        been implemented. 
        
        :param soap_message_request: The request soap message as a string
        :param spaces: Instance of spaces.
        :param mapping_index_rs: Mapping Index Resource. See configuration.xml in mapping package for definition. 
        :rtype: soap response as a string.
        """        
        ext_elements_dict = {}
        edais_path_params = {}
        receipt_exception_data = None
        envelope_element = ElementTree.XML(soap_message_request)
        
        # this is the data required ... we must check for these and raise an error if we don't have them
        data = self.get_handle_declare_status_change_application_data(envelope_element, logger)
        (spear_ref, sender_data, council_ref_1, council_ref_num2, exceptions) = data
        if exceptions:
            # create the data required for the receipt exception signal
            msg_namespace = RECEIPT_EXCEPTION_SIGNAL_MSG_NS
            response_message_key = 'receiptexceptionsignal'
            response_message_name = RECEIPT_EXCEPTION_SIGNAL_MSG_NAME
            receipt_exception_data = {}
            receipt_exception_data['Message'] = 'Missing Elements'
            receipt_exception_data['Reason'] = "\n".join([str(e) for e in exceptions])
            receipt_exception_data['Type'] = 'Invalid Message'
        else:
            msg_namespace = RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NS
            response_message_key = 'receiptacknowledgementsignal'
            response_message_name = RECEIPT_ACKNOWLEDGEMENT_SIGNAL_MSG_NAME
                     
        mapping_uris = mapping_index_rs.mapping_index[response_message_key]
        mapping_resources = {}
        for mapping_uri in mapping_uris:
            mapping_row_rs = self.spaces.get(mapping_uri)
            mapping_resources[mapping_row_rs.edais_national_path] = mapping_row_rs
        logger.log(logging.DEBUG, "%d mapping resources to be used" % len(mapping_resources))
        
        spear_path_params = {'spear_ref': spear_ref}
        edais_pay_load = EDAISPayload(response_message_name, logger)
        sbmh_element = edais_pay_load.create_standard_business_message_header('', 'StandardBusinessMessageHeader', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace, sender_data, spear_ref)
        env = ElementTree.Element('{%s}Envelope' % SOAP_ENV_NS)
        body = ElementTree.SubElement(env, '{%s}Body' % SOAP_ENV_NS)     
        if receipt_exception_data:
            # create the soap fault element
            fault = ElementTree.SubElement(body, '{%s}Fault' % SOAP_ENV_NS)
            fault_code = ElementTree.SubElement(fault, 'faultcode')
            fault_code.text = 'Client'
            fault_string = ElementTree.SubElement(fault, 'faultstring')
            fault_string.text =  receipt_exception_data['Reason']
            fault_detail = ElementTree.SubElement(fault, 'detail')
            msg = ElementTree.SubElement(fault_detail, '{%s}%s' % (msg_namespace, response_message_name)) 
            receipt_exception = edais_pay_load.create_receipt_exception('', 'ReceiptException', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace, receipt_exception_data)
            msg.append(receipt_exception)
        else:
            msg = ElementTree.SubElement(body, '{%s}%s' % (msg_namespace, response_message_name))
            receipt_acknowledgement = edais_pay_load.create_receipt_acknowledgement('', 'ReceiptAcknowledgement', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace)                       
            msg.append(receipt_acknowledgement)
        msg.append(sbmh_element)
        return self.get_elements_as_string(env)        
        
    def handle_query_public_status_application(self, soap_message_request, spaces, mapping_index_rs, xsd_url, logger):
        """
        Handles the service call by parsing the request and generating the response. The service will grab an application
        off the queue and return that as the response. Currently the implementation is to go off and get the application 
        from SPEAR which matches the ApplicationNumber. This is because the application queue functionality has 
        yet to be implemented. 
        
        :param soap_message_request: The request soap message as a string
        :param spaces: Instance of spaces.
        :param mapping_index_rs: Mapping Index Resource. See configuration.xml in mapping package for definition. 
        :rtype: soap response as a string.
        """
        envelope_element = ElementTree.XML(soap_message_request)     
        
        # this is the data required ... we must check for these and raise an error if we don't have them
        application_number = envelope_element.find('./{%s}Body/{%s}%s/{%s}Application/{%s}ApplicationNumber' 
                                                   % (SOAP_ENV_NS, QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NS, QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NAME, QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NS, da_data_tns))
        request_message_namespace = QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NS 
        request_message_name = QUERY_REQUEST_PUBLIC_STATUS_APPLICATION_QUERY_MSG_NAME
        sender_data = self.get_sender_data(request_message_namespace, request_message_name, envelope_element)
        spear_ref = application_number.text
        logger.log(logging.INFO, "Application Number: %s" % spear_ref)
        
        mapping_uris = mapping_index_rs.mapping_index['replypublicstatusapplicationresponse']
        mapping_resources = {}
        for mapping_uri in mapping_uris:
            mapping_row_rs = self.spaces.get(mapping_uri)
            mapping_resources[mapping_row_rs.edais_national_path] = mapping_row_rs
        logger.log(logging.DEBUG, "%d mapping resources to be used" % len(mapping_resources))
        msg_namespace = REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NS
        
        # just return a dummy response for the connectivity test
        if spear_ref == 'connectivitytest':
            ext_elements_dict = {}
            spear_path_params = {'spear_ref': spear_ref}
            edais_path_params = {} 
            
            # create response.  
            edais_pay_load = EDAISPayload(REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME, logger)
            # create the minimum application as the application element is a required element in the response message.
            application_element = self.create_end_of_queue_application(msg_namespace, spear_ref)
            sbmh_element = edais_pay_load.create_standard_business_message_header('', 'StandardBusinessMessageHeader', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace, sender_data, spear_ref)
            env = self.construct_reply_public_status_application_response_edais_soap_message(application_element, None, sbmh_element)
            return self.get_elements_as_string(env)            
        else:    
            # check that the application is in spaces
            app_res = spaces.get(Uri('spear:app/%s' % spear_ref))
            # if the application is insync then return it
            if app_res and app_res.state == a2p_service.A2PService.APPSTATE_INSYNCWITHSPEAR:
                logger.log(logging.INFO, 'App %s is insync with SPEAR' % spear_ref)
                logger.log(logging.DEBUG, app_res)
                ext_elements_dict = {}
                spear_path_params = {'spear_ref': spear_ref}
                edais_path_params = {} 
                
                # create response
                edais_pay_load = EDAISPayload(REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME, logger)
                application_element = edais_pay_load.create_application('', 'Application', mapping_resources, spaces, spear_path_params, edais_path_params, ext_elements_dict, msg_namespace)
                specialisation_element = edais_pay_load.create_specialisation('', 'Specialisation', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace)
                sbmh_element = edais_pay_load.create_standard_business_message_header('', 'StandardBusinessMessageHeader', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace, sender_data, spear_ref)
                env = self.construct_reply_public_status_application_response_edais_soap_message(application_element, specialisation_element, sbmh_element)
                return self.get_elements_as_string(env)            
            # send back end of queue message                       
            else:
                if app_res:
                    logger.log(logging.INFO, 'App %s is not in insync state' % spear_ref)
                else:
                    logger.log(logging.INFO, 'App %s doesnt exists in adpator' % spear_ref)
                ext_elements_dict = {}
                spear_path_params = {'spear_ref': spear_ref}
                edais_path_params = {}      
                
                # create response.  
                edais_pay_load = EDAISPayload(REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME, logger)
                # create the minimum application as the application element is a required element in the response message.
                application_element = self.create_end_of_queue_application(msg_namespace, spear_ref)
                sbmh_element = edais_pay_load.create_standard_business_message_header('', 'StandardBusinessMessageHeader', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, msg_namespace, sender_data, spear_ref)
                env = self.construct_reply_public_status_application_response_edais_soap_message(application_element, None, sbmh_element)
                
                # this is currently put in here to retrieve an application. When the queue is implemented this code can be deleted.
                arguments_dict = {}
                arguments_dict["spearReferenceNumber"] = spear_ref
                rs = Resource(type='term:eplanning/spear/a2p_service/a2prequest')
                rs.set_var('a2p:request/uri', "a2puserreq:getapplication")
                rs.set_var("arguments_dict", arguments_dict)
                app_response_uri = self.spaces.put(Uri('internal:eplanning/spear/a2p_service/a2prequest'), rs)
                logger.log(logging.INFO, app_response_uri)            
                return self.get_elements_as_string(env)

    def construct_reply_public_status_application_response_edais_soap_message(self, application_element, specialisation_element, sbmh_element):
        """
        Constructs the ReplyPublicStatusApplicationResponse payload. The method takes the application element,
        the specialisation element and standard business message header element and combines them to create the
        response message.
        
        :param application_element: Application element.
        :param specialisation_element: Specialisation element.
        :param sbmh_element: Standard Business Message Header element. 
        :rtype: SOAP envelope element.
        """
        env = ElementTree.Element('{%s}Envelope' % SOAP_ENV_NS)
        body = ElementTree.SubElement(env, '{%s}Body' % SOAP_ENV_NS)
        msg = ElementTree.SubElement(body, '{%s}%s' % (REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NS, REPLY_PUBLIC_STATUS_APPLICATION_RESPONSE_MSG_NAME))
        # the application should always be present.
        msg.append(application_element)
        if specialisation_element is not None:
            msg.append(specialisation_element)
        # the standard business message header should always be present.
        msg.append(sbmh_element)
        return env
        
    def get_elements_as_string(self, root_element):
        class dummy:
            pass    
        data = []
        file = dummy()
        file.write = data.append
        ElementTree.ElementTree(root_element).write(file, None)
        return "".join(data)

class EDAISPayload():
    
    def __init__(self, message_name, logger):
        self.logger = logger
        self.message_name = message_name
        self.ref_id = 0
        self.instance_id = 0
        self.date_time = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S')

    def add_to_ext_elements_dict(self, ext_elements_dict, element_name, element):
        """
        Adds the extension element to a extension elements dictionary.
        
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param element_name: Name of the element to be added to the dictionary.
        :param element: Element to be added to the dictionary.
        :rtype: None
        """
        if element:
            if element_name in ext_elements_dict:
                ext_elements_dict[element_name].append(element)
            else:
                ext_elements_dict[element_name] = [element]
                    
    def create_additional_information(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National AdditionInformation Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        # we only store the current version of a document so there will only be one attachment
        self.create_attachment(current_path, 'Attachment', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.get_instance_id())
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_address(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Address Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        ref_id = self.get_ref()
        address_extension = self.create_address_extension(current_path, 'Address', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, ext_data_tns, ref_id)
        self.create_element('BuildingNumber', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('CityName', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('CountryName', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('CountrySubDivision', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        self.create_element('Postcode', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('StreetName', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('StreetType', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        
        if address_extension:
            return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, ref_id, min_elements_required=2)
        else:
            return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)        

    def create_address_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, ref_id):
        """
        Creates the Extension Address Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param ref_id: reference id.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/[vic]' + element_name
        elements_list = []
        self.create_element('CouncilPropertyNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CrownAllotmentNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('FolioNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('NoVolFolReason', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Other', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ParishName', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('PlanNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('PropertyLotNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Section', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('SectionNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)        
        self.create_element('SPI', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('UnitNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('VolumeNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        type = self.create_type(element_name, elements_list, [], namespace, ref_id=ref_id)
        self.add_to_ext_elements_dict(ext_elements_dict, element_name, type)
        return type    
        
    def create_application(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, ext_elements_dict, namespace):
        """
        Creates the National Application Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = 'Application'
        nat_elements_list = []
    
        ref_id = self.get_ref()
        extension_application = self.create_application_extension(current_path, 'Application', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, ext_data_tns, ref_id)
            
        # create additional information
        additional_information_path = self.do_substitute_params('spear:app/$spear_ref#attachments.AdditionalInformation', spear_path_params)
        additionalinformation_attachments = spaces.get_res_part(Uri(additional_information_path))
        if additionalinformation_attachments:
            doc_ids = additionalinformation_attachments.keys()
            doc_ids.sort()
            for doc_id in doc_ids:
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params["doc_id"] = doc_id
                self.create_additional_information(current_path, 'AdditionalInformation', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)

        self.create_element('ApplicationNumber', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        
        # create 'other' attachments
        attachments_path = self.do_substitute_params('spear:app/$spear_ref#attachments.Attachment', spear_path_params)
        attachments = spaces.get_res_part(Uri(attachments_path))
        if attachments:
            for doc_id in attachments.keys():
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params["doc_id"] = doc_id
                copy_spear_path_params["doc_type"] = "Attachment"
                self.create_attachment(current_path, 'Attachment', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
            
        # create planning permit
        planning_permit_path = self.do_substitute_params('spear:app/$spear_ref#attachments.PlanningPermit', spear_path_params)
        planning_permit_attachments = spaces.get_res_part(Uri(planning_permit_path))
        if planning_permit_attachments:
            doc_ids = planning_permit_attachments.keys()
            doc_ids.sort()
            for doc_id in doc_ids:
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params["doc_id"] = doc_id
                copy_spear_path_params["doc_type"] = "PlanningPermit"
                copy_spear_path_params["Doc_Type_Suffix"] = "Planning_Permit"
                self.create_determination(current_path, 'Determination', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        
        # create amended planning permits
        amended_planning_permit_path = self.do_substitute_params('spear:app/$spear_ref#attachments.AmendedPlanningPermit', spear_path_params)
        amended_planning_permit_attachments = spaces.get_res_part(Uri(amended_planning_permit_path))
        if amended_planning_permit_attachments:
            doc_ids = amended_planning_permit_attachments.keys()
            doc_ids.sort()
            for doc_id in doc_ids:
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params["doc_id"] = doc_id
                copy_spear_path_params["doc_type"] = "AmendedPlanningPermit"
                copy_spear_path_params["Doc_Type_suffix"] = "Amended_Planning_Permit"
                self.create_determination(current_path, 'Determination', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)        

        # create events
        event_codes = ['Modified', 'Supplied']
        for event_code in event_codes:
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['eventcode'] = event_code
            self.create_event(parent_path, 'Event', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
            
        party_role_types = ['Applicant', 'Owner']
        for party_role_type in party_role_types:
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['partyroletype'] = party_role_type
            self.create_party_role(current_path, 'PartyRole', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        
        # create public notification obligations
        public_notification_obligation_path = self.do_substitute_params('spear:app/$spear_ref#attachments.AdvertisingInstructions', spear_path_params)
        public_notification_obligation_attachments = spaces.get_res_part(Uri(public_notification_obligation_path))
        if public_notification_obligation_attachments:
            doc_ids = public_notification_obligation_attachments.keys()
            doc_ids.sort()
            for doc_id in doc_ids:
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params["doc_id"] = doc_id
                self.create_public_notification_obligation(current_path, 'PublicNotificationObligation', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)        
        
        self.create_referenced_application(current_path, 'ReferencedApplication', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        
        # create referral responses
        referrals_path = self.do_substitute_params('spear:app/$spear_ref#referrals', spear_path_params)
        referrals = spaces.get_res_part(Uri(referrals_path))
        if referrals:
            for index in range(len(referrals)):
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params['referral_index'] = index
                self.create_referral_obligation(current_path, 'ReferralObligation', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
            
        self.create_element('Status', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        
        if extension_application:
            return self.create_type(element_name, nat_elements_list, [], namespace, ref_id)
        else:
            return self.create_type(element_name, nat_elements_list, [], namespace)

    def create_application_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, ref_id):
        """
        Creates the Extension Application Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param ref_id: reference id.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/[vic]' + element_name
        elements_list = []
        self.create_element('AcceptedFlag', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CHMPDeclaration', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Classification', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CompletedFlag', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CovenantDeclaration', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CovenantDeclarationComment', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('CurrentUse', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('DealingTypeDescription', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('EstimatedDevelopmentCost', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('NumberOfLots', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('PlanningPermitRequirement', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)        
        self.create_element('PlanNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ProposedUse', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ResponsibleAuthorityReferenceNumber1', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ResponsibleAuthorityReferenceNumber2', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('StageNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        trigger_path = self.do_substitute_params('spear:app/$spear_ref#application.Proposal_Type_Trigger_List', spear_path_params)        
        trigger_uri = Uri(trigger_path)
        trigger_list = spaces.get_res_part(Uri(trigger_uri))
        if trigger_list:
            i = 0
            while i < len(trigger_list):
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params['trigger_index'] = i
                self.create_trigger_extension(current_path, 'Trigger', mapping_resources, spaces, copy_spear_path_params, edais_path_params, elements_list, ext_elements_dict, ext_data_tns)
                i += 1
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Version', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        
        type = self.create_type(element_name, elements_list, [], namespace, ref_id=ref_id)
        self.add_to_ext_elements_dict(ext_elements_dict, element_name, type)
        return type
    
    def create_attachment(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Attachment Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        ref_id = self.get_ref()
        self.create_attachment_extension(current_path, 'Attachment', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, ext_data_tns, ref_id)
        self.create_element('Date', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('Format', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)        
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.get_instance_id())
        self.create_element('Size', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('Subject', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)        
        self.create_element('Version', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)                
        self.create_element('URI', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)        
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, ref_id=ref_id, min_elements_required=2)

    def create_attachment_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, ref_id):
        """
        Creates the Extension Attachment Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param ref_id: reference id.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/[vic]' + element_name
        elements_list = []
        self.create_element('DocID', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        if current_path + '/DocType' in mapping_resources and current_path == 'Application/ReferralObligation/ReferralResponse/Attachment/[vic]Attachment':
            self.logger.log(logging.INFO, "Doc Type is %s" % spaces.get_res_part(Uri(self.do_substitute_params(mapping_resources[current_path + '/DocType'].data_uri, spear_path_params))))
            self.logger.log(logging.INFO, "Doc Type is %s" % spaces.get_res_part(Uri(self.do_substitute_params('spear:app/$spear_ref#attachments.RA Response.$doc_id.Doc_Type', spear_path_params))))
        doc_type_element = self.create_element('DocType', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('DocTypeDescription', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('DueDate', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ModifiedAtLVRequest', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('NumberOfDays', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('NumberOfPages', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ObjectionNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ObjectionWithdrawn', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Outcome', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('OwnerType', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)        
        party_types = ['Authoriser', 'AttachmentOwner']
        for party_type in party_types:
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['partytype'] = party_type
            copy_spear_path_params = spear_path_params.copy()
            if doc_type_element:
                copy_spear_path_params['doc_type'] = doc_type_element.text
            self.create_party(current_path, 'Party', mapping_resources, spaces, copy_spear_path_params, copy_edais_path_params, elements_list, ext_elements_dict, ext_data_tns)
        self.create_element('Prefix', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Section', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Suffix', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('SurveyorPlanVersion', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('VersionDescription', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('VolFol', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)            
        type = self.create_type(element_name, elements_list, [], namespace, ref_id=ref_id)
        self.add_to_ext_elements_dict(ext_elements_dict, element_name, type)
        return type    
    
    def create_business_scope(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Business Scope Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """                
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)

    def create_document_identification(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, data):
        """
        Creates the National Document Identification Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param spear_ref: SPEAR Reference Number.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """                
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('CreationDateTime', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, self.date_time)
        self.create_element('InstanceID', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, data[SENDER_DOC_ID_INSTANCE_ID])
        self.create_element('Standard', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, self.message_name)
        self.create_element('TypeVersion', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
        
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
       
    def create_contact(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Contact Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        self.create_person_name(current_path, 'PersonName', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_council_reference_numbers_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_elements_list, ext_elements_dict, namespace):
        """
        Creates the Extension Council Reference Numbers Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        elements_list = []
        self.create_element('ResponsibleAuthorityReferenceNumber1', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ResponsibleAuthorityReferenceNumber2', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        return self.create_type(element_name, elements_list, parent_elements_list, namespace)
    
    def create_element(self, element_name, parent_path, mapping_resources, spaces, spear_path_params, parent_elements_list, namespace, value=None):
        """
        Creates a custom element based on the information given..
        
        :param element_name: Name of the element to be created
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param parent_elements_list: List of the elements of the parent element.
        :param namespace: Namespace of which the element belongs to.
        :param value: Value to be used instead of the data from the resource in spaces.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        data = None
        passed_condition = False
        if not value:
            current_path = '/'.join([parent_path, element_name])
            if current_path in mapping_resources:
                mapping_row = mapping_resources[current_path]
                if mapping_row.check_data_uri:
                    check_data_uri = self.do_substitute_params(mapping_row.check_data_uri, spear_path_params)
                    if (spaces.get_res_part(Uri(check_data_uri)) and mapping_row.condition == 'Exist') \
                        or (not spaces.get_res_part(Uri(check_data_uri)) and mapping_row.condition == 'NotExist'):
                        passed_condition = True
                if not mapping_row.check_data_uri or (mapping_row.check_data_uri and passed_condition): 
                    if mapping_row.constant:
                        data = mapping_row.constant
                    else:
                        data_uri = self.do_substitute_params(mapping_row.data_uri, spear_path_params)
                        data = spaces.get_res_part(Uri(data_uri))
        else:
            data = value
        if data is not None:
            element = ElementTree.Element('{%s}%s' % (namespace, element_name))
            if type(data) is types.BooleanType:
                if data:
                    element.text = '1'
                else:
                    element.text = '0'
                parent_elements_list.append(element)
            else:
                data = str(data)
                if data.strip() != "":
                    element.text = str(data).strip()
                    parent_elements_list.append(element)
            return element
    
    def create_event(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Event Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """             
        current_path_template = parent_path + '/' + element_name + '(${eventcode})'
        current_path = self.do_substitute_params(current_path_template, edais_path_params)
        nat_elements_list = []
        self.create_element('DateTime', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('EventCode', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, edais_path_params['eventcode'])
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
    
    def create_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_elements_list, ext_elements_dict, namespace):
        """
        Creates the Jurisdictional Extension Complex Type.
        
        :param parent_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + '/' + element_name
        ext_elements_dict['CouncilReferenceNumbers'] = self.create_council_reference_numbers_extension(current_path, 'CouncilReferenceNumbers', mapping_resources, spaces, spear_path_params, edais_path_params, [], ext_elements_dict, ext_elements_dict)
        elements_in_extension = ['Address', 
                                 'Application', 
                                 'Attachment', 
                                 'CouncilReferenceNumbers', 
                                 'TransferRequirements',
                                 'ReferencedApplication',
                                 'Event',
                                 'PartyRole']
        elements_list = []
        for element_in_extension in elements_in_extension:
            if element_in_extension in ext_elements_dict and ext_elements_dict[element_in_extension]:
                elements_list.extend(ext_elements_dict[element_in_extension])        
        return self.create_type('Extension', elements_list, parent_elements_list, namespace)

    def create_determination(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Determination Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path  + '/' + element_name
        nat_elements_list = []
        # we only store the current version of a document so there will only be one attachment
        self.create_attachment(current_path, 'Attachment', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Comments', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.get_instance_id())
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
    
    def create_internet(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Internet Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path_template = parent_path + '/' + element_name + '(${internettype})'
        current_path = self.do_substitute_params(current_path_template, edais_path_params)
        nat_elements_list = []
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, edais_path_params['internettype'])
        self.create_element('URI', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
    
    def create_organisation(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Organisation Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_contact(current_path, 'Contact', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        internet_types = ['Email']
        for internet_type in internet_types:
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['internettype'] = internet_type
            self.create_internet(current_path, 'Internet', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_organisation_name(current_path, 'OrganisationName', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_address(current_path, 'PostalAddress', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_telephone(current_path, 'Telephone', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
    
    def create_partner(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, data=None):
        """
        Creates the National Partner Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param data: If data is passed in, then we will not go to spaces for data. This is usually passed in when creating the "receiver" partner section.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        if data:
            self.create_element('Authority', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, data['Authority'])
            self.create_element('ID', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, data['ID'])
            self.create_element('ProcessRole', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, data['ProcessRole'])
        else:
            self.create_element('Authority', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
            self.create_element('ID', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
            self.create_element('ProcessRole', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_organisation_name(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National OrganisationName Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Classification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('Name', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
                
    def create_party_role(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National PartyRole Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """                         
        current_path_template = parent_path + '/' + element_name + '(${partyroletype})'
        current_path = self.do_substitute_params(current_path_template, edais_path_params)
        nat_elements_list = []
        if edais_path_params['partyroletype'] == 'Owner':
            owner_list_uri = self.do_substitute_params('spear:app/$spear_ref#Owner', spear_path_params)
            owner_list = spaces.get_res_part(Uri(owner_list_uri))
            i = 0
            if owner_list:
                copy_spear_path_params = spear_path_params.copy()
                copy_spear_path_params['id'] = i
                copy_edais_path_params = edais_path_params.copy()
                copy_edais_path_params['partytype'] = ''
                self.create_party(current_path, 'Party', mapping_resources, spaces, copy_spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        elif edais_path_params['partyroletype'] == 'RA':
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['partytype'] = ''
            self.create_party(current_path, 'Party', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        else:
            party_types = ['PrimaryApplicant', 'Contact']
            for party_type in party_types:
                copy_edais_path_params = edais_path_params.copy()
                copy_edais_path_params['partytype'] = party_type
                self.create_party(current_path, 'Party', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, edais_path_params['partyroletype'])                
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_party(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National PartyRole Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """     
        if edais_path_params['partytype']:
            current_path_template = parent_path + '/' + element_name + '(${partytype})'
            current_path = self.do_substitute_params(current_path_template, edais_path_params)
        else:
            current_path = parent_path + '/' + element_name
        nat_elements_list = []
        
        self.create_organisation(current_path, 'Organisation', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_person(current_path, 'Person', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        
        person = False
        for nat_element in nat_elements_list:
            if nat_element.tag == '{%s}Person' % naa_data_tns:
                person = True
                break
            elif nat_element.tag == '{%s}Organisation' % naa_data_tns:
                person = False
                break
        
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        if person:
            self.handle_party_name_for_person(current_path, mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        else:
            self.create_element('Name', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)        
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, edais_path_params['partytype'])
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=3)
    
    def create_period(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Period Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        self.create_element('Start', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
    
    def create_person(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Person Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, self.get_instance_id())
        internet_types = ['Email']
        for internet_type in internet_types:
            copy_edais_path_params = edais_path_params.copy()
            copy_edais_path_params['internettype'] = internet_type
            self.create_internet(current_path, 'Internet', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)        
        self.create_person_name(current_path, 'PersonName', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_address(current_path, 'PostalAddress', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        self.create_telephone(current_path, 'Telephone', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_person_name(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National PersonName Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Classification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('FamilyName', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('Name', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('Title', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_public_notification_obligation(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Public NotificationObligation Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_attachment(current_path, 'Attachment', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.get_instance_id())
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)

    def create_receipt_acknowledgement(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Receipt Acknowledgement Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, self.get_instance_id())
        self.create_element('Timestamp', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, self.date_time)        
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_receipt_exception(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, receipt_exception_data):
        """
        Creates the National Receipt Exception Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param receipt_exception_data: Dictionary that contains the values for this type.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Message', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, receipt_exception_data['Message'])
        self.create_element('Reason', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, receipt_exception_data['Reason'])
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns, receipt_exception_data['Type'])        
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_referenced_application(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Referenced Application Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        ref_id = self.get_ref()
        referenced_application_extension = self.create_referenced_application_extension(current_path, 'ReferencedApplication', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns, ref_id)
        self.create_element('ApplicationNumber', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.date_time)
        if referenced_application_extension:
            return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, ref_id)

    def create_referenced_application_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, ref_id):
        """
        Creates the Extension Referenced Application Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param ref_id: reference id.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/[vic]' + element_name
        elements_list = []
        self.create_person_name(current_path, 'PersonName', mapping_resources, spaces, spear_path_params, edais_path_params, elements_list, ext_elements_dict, ext_data_tns)
        self.create_element('PlanningPermitNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('PreviousSPEARReferenceNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('ResponsibleAuthorityReferenceNumber', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        type = self.create_type(element_name, elements_list, [], namespace, ref_id=ref_id)
        self.add_to_ext_elements_dict(ext_elements_dict, element_name, type)
        return type
    
    def create_referral_obligation(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Referral Obligation Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('Description', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('Identification', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns, self.get_instance_id())
        self.create_period(current_path, 'Period', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        copy_edais_path_params = edais_path_params.copy()
        copy_edais_path_params['partyroletype'] = 'RA'
        self.create_party_role(current_path, 'ReferralAuthorityPartyRole', mapping_resources, spaces, spear_path_params, copy_edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        # create referral responses
        referral_response_path = self.do_substitute_params('spear:app/$spear_ref#referrals.$referral_index.referral_response_document_id_list', spear_path_params)
        referral_response_doc_ids = spaces.get_res_part(Uri(referral_response_path))
        for referral_response_doc_id in referral_response_doc_ids:
            copy_spear_path_params = spear_path_params.copy()
            copy_spear_path_params['doc_id'] = referral_response_doc_id
            self.logger.log(logging.INFO, 'Doc Id for referral %s' % referral_response_doc_id)
            self.create_referral_response(current_path, 'ReferralResponse', mapping_resources, spaces, copy_spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace, min_elements_required=2)
        
    def create_referral_response(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Referral Response Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_attachment(current_path, 'Attachment', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        self.create_element('Comments', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('ResponseDate', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, da_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_specialisation(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Specialisation Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + 'Specialisation'
        specialisation_elements_list = []
        self.create_element('DomainId', current_path, mapping_resources, spaces, None, specialisation_elements_list, spec_data_tns)
        self.create_extension(current_path, 'Extension', mapping_resources, spaces, spear_path_params, edais_path_params, specialisation_elements_list, ext_elements_dict, spec_data_tns)
        self.create_element('Jurisdiction', current_path, mapping_resources, spaces, None, specialisation_elements_list, spec_data_tns)
        self.create_element('Version', current_path, mapping_resources, spaces, None, specialisation_elements_list, spec_data_tns)        
        return self.create_type(element_name, specialisation_elements_list, [], namespace)
    
    def create_standard_business_message_header(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace, sender_data, spear_ref):
        """
        Creates the National Standard Business Message Header Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :param sender_data: Required data about the Sender.
        :param spear_ref: SPEAR Reference Number.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """
        current_path = parent_path + element_name
        nat_elements_list = []
        self.create_business_scope(current_path, 'BusinessScope', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, msg_data_tns)
        self.create_document_identification(current_path, 'DocumentIdentification', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, msg_data_tns, sender_data)
        self.create_partner(current_path, 'ReceiverPartner', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, msg_data_tns, sender_data)
        self.create_partner(current_path, 'SenderPartner', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, msg_data_tns)
        self.create_element('Version', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, msg_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_subject_land(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Telephone Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_address(current_path, 'Address', mapping_resources, spaces, spear_path_params, edais_path_params, nat_elements_list, ext_elements_dict, da_data_tns)
        return self.create_type(element_name, nat_elements_list, parent_nat_elements_list, namespace)
    
    def create_telephone(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Creates the National Telephone Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        current_path = parent_path + '/' + element_name
        nat_elements_list = []
        self.create_element('AreaCode', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        self.create_element('Number', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns)
        for nat_element in nat_elements_list:
            if nat_element.tag == '{%s}Number' % naa_data_tns:
                if nat_element.text.startswith('04'):
                    self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, "Mobile")
                else:
                    self.create_element('Type', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, naa_data_tns, "Fixed Line")
        return self.create_type('Telephone', nat_elements_list, parent_nat_elements_list, namespace)            
                    
    def create_trigger_extension(self, parent_path, element_name, mapping_resources, spaces, spear_path_params, edais_path_params, parent_elements_list, ext_elements_dict, namespace):
        """
        Creates the Extension Trigger Complex Type.
        
        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param element_name: Name of the element instance for this type.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """         
        current_path = parent_path + '/' + element_name
        elements_list = []
        self.create_element('Tier1Trigger', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        self.create_element('Tier2Trigger', current_path, mapping_resources, spaces, spear_path_params, elements_list, ext_data_tns)
        
        return self.create_type('Trigger', elements_list, parent_elements_list, namespace)

    def create_type(self, type_name, elements_list, parent_elements_list, namespace, ref_id=None, min_elements_required=1):
        """
        Creates a Complex Type with all the elements for the type and adds the type to the parents element list.
        
        :param type_name: Name of the type to be created.
        :param elements_list: List of elements to add to the type.
        :param parent_elements_list: List of the elements of the parent element.
        :param namespace: Namespace of which the element belongs to.
        :param ref_id: Value to be set as the ref_id for the type.
        :param min_elements_required: Number of elements required in the elements_list in order to create the type.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """          
        
        if len(elements_list) >= min_elements_required:
            type_element = ElementTree.Element('{%s}%s' % (namespace, type_name))
            if ref_id:
                type_element.set("ref", str(ref_id))
            for element in elements_list:
                type_element.append(element)
            parent_elements_list.append(type_element)
            return type_element

    def do_substitute_params(self, template_string, params):
        """
        Evaluates a template string with the parameters passed in.
        
        :param template_string: Template to be evaluated.
        :param params: Parameters for the template1.
        :rtype: String
        """                
        s = Template(template_string)
        return s.substitute(params)
    
    def get_instance_id(self):
        """
        Returns a unique value to be used as a identifier for a element.
        
        :rtype: String
        """                
        self.instance_id += 1
        return str(self.instance_id)
    
    def get_ref(self):
        """
        Returns a unique value to be used as a reference between a national and extension elements.

        :rtype: String
        """        
        self.ref_id += 1
        return self.ref_id
        
    def handle_party_name_for_person(self, parent_path, mapping_resources, spaces, spear_path_params, edais_path_params, parent_nat_elements_list, ext_elements_dict, namespace):
        """
        Handles the PartyName case when the party is an individual. Because the rules around this are too complex to represent in the spreadsheet, it rules are hardcoded here.

        :param parent_path: Path of the caller. This path's format corresponds to the path in the edais_national_path column in the spreadsheet.
        :param mapping_resources: Dictionary where the 'edais_national_path' is the key and the value is the mapping row resource.
        :param spaces: Spaces
        :param spear_path_params: Dictionary that contains the parameters required to evaluate a spear adaptor path which contains parameters. key="parameter name", value="parameter value".
        :param edais_path_params: Dictionary that contains the parameters required to evaluate a edais path which contains parameters. key="parameter name", value="parameter value".
        :param parent_nat_elements_list: List of the elements of the parent element.
        :param ext_elements_dict: Dictionary that contains all the extension instances to be added to the extension element in specialisation.
        :param namespace: Namespace of which the element belongs to.
        :rtype: Element if element is required to be created, and None if no element is required to be created.
        """            
        current_path = parent_path
        nat_elements_list = parent_nat_elements_list
        party_role_type = None
        party_type = None
        if 'partyroletype' in edais_path_params:
            party_role_type = edais_path_params['partyroletype']
        if 'partytype' in edais_path_params:
            party_type = edais_path_params['partytype']
        if party_role_type == 'Authoriser' and party_type == None:
            pass
        elif party_role_type == 'Applicant' and party_type == 'PrimaryApplicant':
            data_uri_template_1 = "spear:app/$spear_ref#application.Applicant_Name_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#application.Applicant_Name_Last_Name"
        elif party_role_type == 'Applicant' and party_type == 'Contact':
            data_uri_template_1 = "spear:app/$spear_ref#application.ApplicantContact_Name_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#application.ApplicantContact_Name_Last_Name"
        elif party_role_type == 'AssessmentAuthority' and party_type == None:
            # this case won't occur according to spreadsheet
            return
        elif party_role_type == 'Owner' and party_type == None:
            data_uri_template_1 = "spear:app/$spear_ref#application.Owner.$id.Name_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#application.Owner.$id.Name_Last_Name"
        elif party_role_type == None and party_type == 'Authoriser':
            data_uri_template_1 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Authenticated_by_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Authenticated_by_Last_Name"
        elif party_role_type == None and party_type == 'AttachmentOwner':
            data_uri_template_1 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Owner_ApplicantContact_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Owner_ApplicantContact_Last_Name"
        elif party_role_type == None and party_type == 'OnlineObjector':
            data_uri_template_1 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Current_Document_Suffix_Online_Objector_First_Name"
            data_uri_template_2 = "spear:app/$spear_ref#attachments.$doc_type.$doc_id.Current_Document_Suffix_Online_Objector_Name_Name"
        elif party_role_type == None and party_type == 'ConsentingReferralAuthority':
            # this case won't occur according to spreadsheet
            return
        else:
            raise Exception("Combination of Party Role Type and Party Type not accounted for.")
        data_uri_1 = self.do_substitute_params(data_uri_template_1, spear_path_params)
        data_uri_2 = self.do_substitute_params(data_uri_template_2, spear_path_params)
        data_1 = spaces.get_res_part(Uri(data_uri_1))
        data_2 = spaces.get_res_part(Uri(data_uri_2))
        value = data_1 + data_2
        return self.create_element('Name', current_path, mapping_resources, spaces, spear_path_params, nat_elements_list, namespace, value)
         
if __name__ == "__main__":
    finds = re.findall('{.*?}[^{]*', './{http://b}B/{http://c}C/{http://d}D')
    for find in finds:
        print find
        matches = re.match('{(.*?)}([^/]*)', find)
        print matches.group(1)
        print matches.group(2)